BackForward

/*----------------------------------------\
| Print datasets;                                                    |
|-------------------------------------------|
|--------------------------------------------------------------------|
|---------------------------|
| No argument is needed; but there are several optional arguement:   |
| indata: if no indata is provided, print the latest data generated; |
| var: the variable names to be printed; if not provided, print all; |
| where: define a subset of the datasets; if not provided, print all;|
| groupby: groupby statement, how do you want to group the variables;|
| having: use the statistics associated with groupby to select data; |
| orderby: print the output data in the order of which variable;     |
| outdata: output dataset; if no, just print to list without output; |
|--------------------------------|
|--------------------------------------------------------------------|
|---------------------------------------|
| Example:                                                           |
| data one;                                                          |
|    input str $ x y z;                                              |
|    LABEL str='character' X='numeric x' y='numeric y' z='numeric z';|
|    datalines;                                                      |
| this 2 1 213                                                       |
| is 23 1 323                                                        |
| a 1243 23 12                                                       |
| test 131 4576 1                                                    |
| to 124 23 32                                                       |
| check 1245 2 3                                                     |
| to 23 32 44                                                        |
|  see 2345 43 65                                                    |
|  if 23 123 090                                                     |
|  print 23 34 21                                                    |
|  works 21 23 322                                                   |
|  ; %print(one, (distinct y, count(*) as numx), groupby=(y),          |
|         orderby=(numx, desc y));                                   |
| Usgae: %print(indata=, var=, inobs=, outobs=, groupby=, having=,     |
|             where=, orderby=, outdata=)/parmbuff;                  |
\----------------------------------------*/
%macro print/parmbuff;
/*--------------------------------------------\
| Copy Right: Duo Zhou;                       |
| Created: 6-16-2001 8:32pm;                  |
| Purpose: Custimable print procedure;        |
\--------------------------------------------*/
%local _newstr_ _dlen_;
%let syspbuff=%substr(%quote(%trim(%quote(%left(%quote(&syspbuff))))), 2, %eval(%length(%trim(%quote(%left(%quote(&syspbuff)))))-2));
%let syspbuff=%sysfunc(translate(%quote(&syspbuff), %str(%'), %str(%")));
%let _dlen_=$%trim(%left(%eval(%length(&syspbuff)+20))); %let _tmplast_=&syslast; %let indata=; %let var=; %let inobs=; %let outobs=;
%let groupby=; %let having=; %let where=; %let orderby=; %let outdata=; %let _viewexist_=; %let _datao_=; %let _newstr_=;
options nonotes;
data _null_; length _string_ _substr0_ &_dlen_; _string_="&syspbuff"; _substr0_='';
   if rxmatch(rxparse("$(1)"),_string_) then do;
      do while(rxmatch(rxparse("$(1)"),_string_)); rx=rxparse("$(1)");
         call rxsubstr(rx,_string_,_pos_,_len_); _substr0_=substr(_string_, _pos_, _len_);
         substr(_string_, _pos_, _len_)=trimn(left(translate(_substr0_, 'À', '(', 'Á', ')', '´', ',', '®', ' ')));
         call rxfree(rx);
      end; output;
   end; call symput('_newstr_', trimn(left(_string_))); run; %local _xvarcnt_ _xvar_; %let _xvarcnt_=0;
%do %while(%length(%qscan(%nrbquote(&_newstr_), %eval(&_xvarcnt_+1), %nrbquote(,))));
   %let _xvarcnt_=%eval(&_xvarcnt_+1); %let _xvar_=%nrbquote(%qscan(%nrbquote(&_newstr_), &_xvarcnt_, %nrbquote(,)));
   %let _xvar_=%sysfunc(translate(%quote(&_xvar_), '(', 'À', ')', 'Á', ',', '´', ' ', '®')); %let _x2_=%trim(%left(%qscan(%quote(&_xvar_), 1, %str(=))));
   %let _x3_=%substr(%quote(&_xvar_), %eval(%index(%quote(&_xvar_),%str(=))+1), %eval(%length(&_xvar_)-%index(%quote(&_xvar_),%str(=))));
    %if (not %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_xvar_))))), %str(=))) and
       ((%quote(&_xvarcnt_) = %quote(1)) or (%quote(&_xvarcnt_) = %quote(2))) %then %do;
      %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_x2_))))), %str(%()) eq 1) and
          (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(&_x2_))))))), %str(%))) eq 1) %then
         %let _x3_=%substr(%quote(%trim(%quote(%left(%quote(&_x2_))))), 2, %eval(%length(%trim(%quote(%left(%quote(&_x2_)))))-2));
      %if (%quote(&_xvarcnt_) = %quote(1)) %then %let indata=&_x3_; %else %let var=&_x3_;
   %end;
   %else %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_x3_))))), %str(%()) eq 1) and
          (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(&_x3_))))))), %str(%))) eq 1) %then
         %let &_x2_=%substr(%quote(%trim(%quote(%left(%quote(&_x3_))))), 2, %eval(%length(%trim(%quote(%left(%quote(&_x3_)))))-2));
   %else %let &_x2_=&_x3_;
%end;
%if (%length(&indata) le 0) %then %let indata=&syslast;
%if (%length(&var) le 0) %then %let _allvars_=*;
%else %do;
   %if (%index(%quote(&var), %str(,))) %then %let vardlm=%quote(,);
   %else %let vardlm=%quote( );
   %if (%index(%quote(&var), %str(-))) %then %do;
      %let _convar_=; %let _dummyvar_=&var;
      %do %while(%index(%quote(&var), %str(-)));
         %let _sub1var_=%substr(%quote(&var), 1, %eval(%index(%quote(&var), %str(-))-1));
         %let var=%substr(%quote(&var), %eval(%index(%quote(&var), %str(-))+1), %eval(%length(&var)-%index(%quote(&var), %str(-)))); %let _tmpvari_=0;
         %do %while(%length(%qscan(%nrbquote(&_sub1var_), %eval(&_tmpvari_+1), %nrbquote(&vardlm))));
            %let _tmpvari_=%eval(&_tmpvari_+1); %let _tmp1var_=%nrbquote(%qscan(%nrbquote(&_sub1var_), &_tmpvari_, %%nrbquote(&vardlm)));
            %if (%length(%qscan(%nrbquote(&_sub1var_), %eval(&_tmpvari_+1), %nrbquote(&vardlm)))) %then %do;
               %if (%quote(&_convar_) eq) %then %let _convar_=%trim(%quote(%left(%quote(&_tmp1var_))));
               %else %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
            %end;
            %else %if ( %eval(%sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp1var_)))+1)) %then %do;
               %let _arrvarbeg_=%substr(%quote(&_tmp1var_), %eval(%sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp1var_)))+1),
                        %eval(%length(&_tmp1var_)- %eval(%sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp1var_))))));
               %let _dummykeyword_=;
               %let _arrvarbroot_=%substr(%quote(&_tmp1var_), 1, %sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp1var_))));
               %if (%sysfunc(indexw(%quote(%upcase(&_arrvarbroot_)),%quote(DISTINCT)))) %then %do;
                  %let _dummykeyword_=distinct ;
                  %let _arrvarbroot_=%sysfunc(tranwrd(%quote(%upcase(&_arrvarbroot_)),%quote(DISTINCT),%quote()));
               %end;
               %if (%quote(&var) ne) %then %do; %let _tmp2var_=%nrbquote(%qscan(%nrbquote(&var), 1, %%nrbquote(&vardlm)));
                  %if (%sysfunc(rxmatch(%sysfunc(rxparse($d $s)),&_tmp2var_))) %then %do;
                     %let _arrvarend_=%substr(%quote(&_tmp2var_), %eval(%sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp2var_)))+1),
                                           %eval(%length(&_tmp2var_)- %eval(%sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp2var_))))));
                     %let _arrvareroot_=%substr(%quote(&_tmp2var_), 1,%sysfunc(rxmatch(%sysfunc(rxparse($- ($a|_))),%quote(&_tmp2var_))));
                     %if (%quote(%lowcase(&_arrvarbroot_)) eq %quote(%lowcase(&_arrvareroot_))) %then %do;
                        %do _locali_=&_arrvarbeg_ %to %eval(&_arrvarend_-1);
                           %if (%quote(&_convar_) eq) %then %let _convar_=%trim(%left(&_arrvarbroot_))%trim(%left(&_locali_));
                           %else %do;
                              %if (%index(%quote(%upcase(&_dummyvar_)), %quote(DISTINCT ))) or (%sysfunc(indexw(%quote(%upcase(&_dummyvar_)), %quote(AS)))) %then %do;
                                 %if (%quote(%upcase(&_convar_)) ne %quote(DISTINCT)) and (%substr(%quote(%upcase(%trim(%quote(%left(%quote(&_convar_)))))), %eval(%length(%trim(%quote(%left(%quote(&_convar_)))))-2),3) ne %quote( AS)) %then
                                    %let _convar_=%trim(%quote(%left(%quote(&_convar_))))(%quote(&vardlm) %trim(%left(&_arrvarbroot_))%trim(%left(&_locali_));
                                 %else %let _convar_=%trim(%quote(%left(%quote(&_convar_)))) %trim(%left(&_arrvarbroot_))%trim(%left(&_locali_));
                              %end;
                              %else %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%left(&_arrvarbroot_))%trim(%left(&_locali_));
                           %end;
                        %end;
                     %end;
                     %else %do;
                        %if (%quote(&_convar_) eq) %then %let _convar_=%trim(%quote(%left(%quote(&_tmp1var_))));
                        %else %do;
                           %if (%index(%quote(%upcase(&_dummyvar_)), %quote(DISTINCT ))) or (%sysfunc(indexw(%quote(%upcase(&_dummyvar_)), %quote(AS)))) %then %do;
                              %if (%quote(%upcase(&_convar_)) ne %quote(DISTINCT)) and (%substr(%quote(%upcase(%trim(%quote(%left(%quote(&_convar_)))))), %eval(%length(%trim(%quote(%left(%quote(&_convar_)))))-2),3) ne %quote( AS)) %then
                                 %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                              %else %let _convar_=%trim(%quote(%left(%quote(&_convar_)))) %trim(%quote(%left(%quote(&_tmp1var_))));
                           %end;
                           %else %let _convar_=%trim(%quote(%left(&_convar_)))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                        %end;
                        %put ==> Alert! Variable name &_tmp1var_ and &_tmp2var_ do not have the same pattern!;
                     %end;
                  %end;
                  %else %do;
                     %if (%quote(&_convar_) eq) %then %let _convar_=%trim(%quote(%left(%quote(&_tmp1var_))));
                     %else %do;
                        %if (%index(%quote(%upcase(&_dummyvar_)), %quote(DISTINCT ))) or (%sysfunc(indexw(%quote(%upcase(&_dummyvar_)), %quote(AS)))) %then %do;
                           %if (%quote(%upcase(&_convar_)) ne %quote(DISTINCT)) and (%substr(%quote(%upcase(%trim(%quote(%left(%quote(&_convar_)))))), %eval(%length(%trim(%quote(%left(%quote(&_convar_)))))-2),3) ne %quote( AS)) %then
                              %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                           %else %let _convar_=%trim(%quote(%left(%quote(&_convar_)))) %trim(%quote(%left(%quote(&_tmp1var_))));
                        %end;
                        %else %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                     %end;
                     %put ==> Alert! Variable name &_tmp2var_ does not have a numeric suffix!;
                  %end;
               %end;
               %else %do;
                  %if (%quote(&_convar_) eq) %then %let _convar_=%trim(%quote(%left(%quote(&_tmp1var_))));
                  %else %do;
                     %if (%index(%quote(%upcase(&_dummyvar_)), %quote(DISTINCT ))) or (%sysfunc(indexw(%quote(%upcase(&_dummyvar_)), %quote(AS)))) %then %do;
                        %if (%quote(%upcase(&_convar_)) ne %quote(DISTINCT)) and (%substr(%quote(%upcase(%trim(%quote(%left(%quote(&_convar_)))))), %eval(%length(%trim(%quote(%left(%quote(&_convar_)))))-2),3) ne %quote( AS)) %then
                           %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                        %else %let _convar_=%trim(%quote(%left(%quote(&_convar_)))) %trim(%quote(%left(%quote(&_tmp1var_))));
                     %end;
                     %else %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                  %end;
                  %put ==> Alert! No variable names are provided after &_tmp1var_ -!;
               %end;
            %end;
            %else %do;
               %if (%quote(&_convar_) eq) %then %let _convar_=%trim(%quote(%left(%quote(&_tmp1var_))));
               %else %do;
                  %if (%index(%quote(%upcase(&_dummyvar_)), %quote(DISTINCT ))) or (%sysfunc(indexw(%quote(%upcase(&_dummyvar_)), %quote(AS)))) %then %do;
                     %if (%quote(%upcase(&_convar_)) ne %quote(DISTINCT)) and (%substr(%quote(%upcase(%trim(%quote(%left(%quote(&_convar_)))))), %eval(%length(%trim(%quote(%left(%quote(&_convar_)))))-2),3) ne %quote( AS)) %then
                        %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
                     %else %let _convar_=%trim(%quote(%left(%quote(&_convar_)))) %trim(%quote(%left(%quote(&_tmp1var_))));
                  %end;
                  %else %let _convar_=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&_tmp1var_))));
               %end;
               %put ==> Alert! Variable name &_tmp1var_ does not have a numeric suffix!;
            %end;
         %end;
      %end;
      %if (%index(%quote(%upcase(&_dummyvar_)), %quote(DISTINCT ))) or (%sysfunc(indexw(%quote(%upcase(&_dummyvar_)), %quote(AS)))) %then %do;
         %if (%quote(%upcase(&_convar_)) ne %quote(DISTINCT)) and (%substr(%quote(%upcase(%trim(%quote(%left(%quote(&_convar_)))))), %eval(%length(%trim(%quote(%left(%quote(&_convar_)))))-2),3) ne %quote( AS)) %then
            %let var=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&var))));
         %else %let var=%trim(%quote(%left(%quote(&_convar_)))) %trim(%quote(%left(%quote(&var))));
      %end;
      %else %let var=%trim(%quote(%left(%quote(&_convar_))))%quote(&vardlm) %trim(%quote(%left(%quote(&var))));
   %end;
   %if (not %index(%quote(&var), %quote(,))) and (not %index(%quote(%upcase(&var)), %quote(DISTINCT ))) and
       (not %sysfunc(indexw(%quote(%upcase(&var)), %quote(AS)))) %then %do;
      %if (%sysfunc(index(%quote(&var),_ALL_))) %then %let var=*;
      %else %if (%sysfunc(index(%quote(%upcase(&var)),_CHARACTER_))) %then %do;
         %if (%sysfunc(exist(&indata))) %then %do; %let _indsid_=%sysfunc(open(&indata)); %let _innvars_=%sysfunc(attrn(&_indsid_,NVARS)); %let _convar_=;
            %do _invari_=1 %to &_innvars_; %let _invtype_=%sysfunc(vartype(&_indsid_, &_invari_));
               %if (not %index(%quote(%upcase(&_invtype_)),%quote(N))) %then %let _convar_= %trim(%left(&_convar_)) %sysfunc(varname(&_indsid_,&_invari_));
            %end; %let _invrc_=%sysfunc(close(&_indsid_)); %let var=&_convar_;
         %end;
      %end;
      %else %if (%sysfunc(index(%quote(%upcase(&var)),_NUMERIC_))) %then %do;
         %if (%sysfunc(exist(&indata))) %then %do; %let _indsid_=%sysfunc(open(&indata)); %let _innvars_=%sysfunc(attrn(&_indsid_,NVARS)); %let _convar_=;
            %do _invari_=1 %to &_innvars_; %let _invtype_=%sysfunc(vartype(&_indsid_, &_invari_));
               %if (%index(%quote(&_invtype_),%quote(N))) %then %let _convar_= %trim(%left(&_convar_)) %sysfunc(varname(&_indsid_,&_invari_));
            %end; %let _invrc_=%sysfunc(close(&_indsid_)); %let var=&_convar_;
         %end;
      %end;
      %else %do;  %let _jvar_=0;
         %do %while(%length(%qscan(%quote(&var), %eval(&_jvar_+1), %quote( ))));
            %let _jvar_=%eval(&_jvar_+1); %let _varj_=%qscan(%quote(&var), &_jvar_, %quote( ));
            %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&_varj_))))), %str(%()))
                and (not %index(%quote(%upcase(%sysfunc(compress(%quote(&_varj_))))),%str(LABEL=))) %then
               %let _varj_=&_varj_ label="&_varj_";
            %if (%quote(&_jvar_) eq 1) %then %let _allvars_=&_varj_;
            %else %if (%length(&_varj_) gt 0) and (%quote(%upcase(&_allvars_)) ne %quote(DISTINCT)) %then
               %let _allvars_=%trim(%bquote(%left(%bquote(&_allvars_)))), &_varj_;
            %else %if (%length(&_varj_) gt 0) and (%quote(%upcase(&_allvars_)) eq %quote(DISTINCT)) %then
               %let _allvars_=%trim(%bquote(%left(%bquote(&_allvars_)))) &_varj_;
         %end;
      %end;
   %end; %else %let _allvars_=&var;
%end;
%if (%length(&groupby) gt 0) %then %do;
   %if (not %index(%quote(&groupby), %quote(,))) %then %do; %let _jgroupby_=0; %let _allgroupbys_=;
      %do %while(%length(%qscan(%quote(&groupby), %eval(&_jgroupby_+1), %quote( ))));
         %let _jgroupby_=%eval(&_jgroupby_+1); %let _groupbyj_=%qscan(%quote(&groupby), &_jgroupby_, %quote( ));
         %if (%quote(&_jgroupby_) eq %quote(1)) %then %let _allgroupbys_=&_groupbyj_;
         %else %if (%length(&_groupbyj_) gt 0) %then %let _allgroupbys_=%trim(%quote(%left(%quote(&_allgroupbys_)))), &_groupbyj_;
      %end; %let groupby=&_allgroupbys_;
   %end;
%end;
%if (%length(&orderby) gt 0) %then %do;
   %if (not %index(%quote(&orderby), %quote(,))) and (not %sysfunc(indexw(%quote(%upcase(&orderby)), %quote(DESC)))) and
       (not %sysfunc(indexw(%quote(%upcase(&orderby)), %quote(DESCENDING)))) and
       (not %sysfunc(indexw(%quote(%upcase(&orderby)), %quote(ASC)))) and
       (not %sysfunc(indexw(%quote(%upcase(&orderby)), %quote(ASCENDING)))) %then %do;
      %let _jorderby_=0; %let _allorderbys_=;
      %do %while(%length(%qscan(%quote(&orderby), %eval(&_jorderby_+1), %quote( ))));
         %let _jorderby_=%eval(&_jorderby_+1); %let _orderbyj_=%qscan(%quote(&orderby), &_jorderby_, %quote( ));
         %if (%quote(&_jorderby_) eq %quote(1)) %then %let _allorderbys_=&_orderbyj_;
         %else %if (%length(&_orderbyj_) gt 0) %then %let _allorderbys_=%trim(%quote(%left(%quote(&_allorderbys_)))), &_orderbyj_;
      %end; %let orderby=&_allorderbys_;
   %end;
   %else %do; %let _jorderby_=0; %let _allorderbys_=;
      %do %while(%length(%qscan(%quote(&orderby), %eval(&_jorderby_+1), %quote(,))));
         %let _jorderby_=%eval(&_jorderby_+1); %let _orderbyj_=%qscan(%quote(&orderby), &_jorderby_, %quote(,));
         %if (%quote(&_jorderby_) eq %quote(1)) %then %do;
            %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(DESC)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(DESC), %quote( ))))))) DESC;
            %else %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(DESCENDING)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(DESCENDING), %quote( ))))))) DESC;
            %else %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(ASC)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(ASC), %quote( ))))))) ASC;
            %else %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(ASCENDING)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(ASCENDING), %quote( ))))))) ASC;
            %else %let _allorderbys_=&_orderbyj_;
         %end;
         %else %if (%length(&_orderbyj_) gt 0) %then %do;
            %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(DESC)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(&_allorderbys_)))), %trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(DESC), %quote( ))))))) DESC;
            %else %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(DESCENDING)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(&_allorderbys_)))), %trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(DESCENDING), %quote( ))))))) DESC;
            %else %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(ASC)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(&_allorderbys_)))), %trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(ASC), %quote( )))))));
            %else %if (%sysfunc(indexw(%quote(%upcase(&orderby)), %quote(ASCENDING)))) %then
               %let _allorderbys_=%trim(%quote(%left(%quote(&_allorderbys_)))), %trim(%quote(%left(%quote(%sysfunc(tranwrd(%quote(%upcase(&_orderbyj_)), %quote(ASCENDING), %quote( )))))));
            %else %let _allorderbys_=%trim(%quote(%left(%quote(&_allorderbys_)))), &_orderbyj_;
         %end;
      %end; %let orderby=&_allorderbys_;
   %end;
%end; %let _idata_=0;
%do %while(%length(%qscan(%quote(&indata), %eval(&_idata_+1), %str( ,))));
   %let _idata_=%eval(&_idata_+1); %let _datai_=%qscan(%quote(&indata), &_idata_, %str( ,));
   %if (%quote(&outdata) ne) %then %let _datao_=%qscan(%quote(&outdata), &_idata_, %str( ,));
   %if (%sysfunc(exist(&_datai_))) or (%sysfunc(exist(&_datai_, VIEW))) %then %do;
      proc sql %if (%length(&inobs) gt 0) %then %do; inobs=&inobs %end;
               %if (%length(&outobs) gt 0) %then %do; outobs=&outobs %end;;
         create table _printtmp1_ as select &_allvars_ from &_datai_ %if (%length(&where) gt 0) %then where &where;
         %if (%length(&groupby) gt 0) %then group by &groupby;
         %if (%length(&having) gt 0) %then having &having;
         %if (%length(&orderby) gt 0) %then order by &orderby;;
      %if (%length(&_datao_) gt 0) %then %do; data &_datao_; set _printtmp1_; run; %end;
      %local _printtmp1dsid_ _printtmp1nobs_ _printtmp1rc_; %let _printtmp1dsid_=%sysfunc(open(_printtmp1_));
      %if &_printtmp1dsid_ %then %do; %let _printtmp1nobs_=%sysfunc(attrn(&_printtmp1dsid_,NOBS)); %let _printtmp1rc_=%sysfunc(close(&_printtmp1dsid_)); %end;
      %else %goto finish;
      %if (%quote(&_printtmp1nobs_) le 0) %then %do; %put --> Alert! No observations were printed!; %goto finish; %end;
      proc contents data=_printtmp1_ out=_printtmp1cnt_(index=(varnum)) noprint;
      proc sql noprint; select name, label into: _printvname_ separated by '¶ ', : _printvlabel_ separated by '¶ '
         from _printtmp1cnt_ order by varnum;
      %let _printvlabel_=%sysfunc(compress(%bquote(&_printvlabel_), %str(%'))); %let _chki_=0; %let _printvariable_=;
      %let _printvlabel_=%sysfunc(compress(%bquote(&_printvlabel_), %str(%"))); %let _printlabel_=LABEL ;
      %do %while(%length(%qscan(%quote(&_printvname_), %eval(&_chki_+1), %quote(¶))));
         %let _chki_=%eval(&_chki_+1); %let _printvar_=%qscan(%quote(&_printvname_), &_chki_, %quote(¶));
         %let _printvariable_=%trim(%left(&_printvariable_)) %trim(%left(&_printvar_));
         %if (%length(%trim(%quote(%left(%quote(&_printvlabel_))))) gt 0) %then %let _printvlabeli_=%qscan(%quote(&_printvlabel_), &_chki_, %quote(¶)); %else %let _printvlabeli_=;
         %if (%length(%trim(%quote(%left(%quote(&_printvlabeli_))))) gt 0) %then
            %let _printlabel_=%trim(%bquote(%left(%bquote(&_printlabel_)))) %trim(%left(&_printvar_))="%trim(%bquote(%left(%bquote(&_printvlabeli_)))) %quote(<%trim(%left(&_printvar_))>)";
         %else %let _printlabel_=%trim(%bquote(%left(%bquote(&_printlabel_)))) %trim(%left(&_printvar_))="%quote(<%trim(%left(&_printvar_))>)";
      %end;
      %local _dsid_ _nobs_ _rc_; %let _dsid_=%sysfunc(open(_printtmp1cnt_));
      %if &_dsid_ %then %do; %let _nobs_=%sysfunc(attrn(&_dsid_,NOBS)); %let _rc_=%sysfunc(close(&_dsid_)); %end;
      %else %do; %put ==> Alert! No variable names were selected!; %goto finish; %end; %local zero;
      %do _i_=1 %to &_nobs_; %local _resizevar_&_i_ _resizetyp_&_i_ _resizelen_&_i_ _resizemln_&_i_; %end;
      data _null_; set _printtmp1cnt_; call symput ('_resizevar_'||left(_n_), name);
         if type=2 then call symput ('_resizetyp_'||left(_n_), '$'); else call symput ('_resizetyp_'||left(_n_), ' ');
         call symput ('_resizelen_'||left(_n_), length);
      proc sql noprint; drop table _printtmp1cnt_;
      select 0
      %do _i_=1 %to &_nobs_; %if &&_resizetyp_&_i_=$ %then ,max(length(&&_resizevar_&_i_)); %end; into :zero
      %do _i_=1 %to &_nobs_; %if &&_resizetyp_&_i_=$ %then ,:_resizemln_&_i_ ; %end; from _printtmp1_;
      data _printtmp2_; &_printlabel_;
         length %do _i_=1 %to &_nobs_; %if &&_resizetyp_&_i_=$ %then %do; &&_resizevar_&_i_ $ &&_resizemln_&_i_ %end; %end;;
         format %do _i_=1 %to &_nobs_; %if &&_resizetyp_&_i_=$ %then %do; &&_resizevar_&_i_ $ &&_resizemln_&_i_... %end; %end;; set _printtmp1_;
      proc print data=_printtmp2_ label OBS; var &_printvariable_; title "Output of PROC PRINT for Dataset «%upcase(%trim(%left(&_datai_)))»";
      run; proc sql noprint; drop table _printtmp1_; drop table _printtmp2_; TITLE " ";quit; options notes;
      %put NOTE: There were %trim(%left(&_printtmp1nobs_)) observations read from the dataset %upcase(%trim(%left(&_datai_))).;
   %end;
   %else %do; %put ==> Alert! Input dataset %upcase(%trim(%left(&_datai_))) does%str(%')t exist!; %goto finish; %end;
   %if (%length(&_datao_) gt 0) %then %let syslast=&_datao_;
%end;
%finish:
%if (%length(&outdata) eq 0) %then %let syslast=&_tmplast_;
%mend print;